3.5 Software API and ROS
Kikobot C1 is controlled from your PC through Kikobot Studio or any custom application using a WebSocket JSON API on port 8080, backed by ROS 2 Humble packages under /opt/kikobot.
1. Starting the C1 software stack
C1 uses the same motion stack and WebSocket bridge as C2; robot_profile in the handshake is "c1".
kikobot-backend c1
| Mode | Command |
|---|---|
| Interactive + RViz | kikobot-backend c1 |
| Headless | export KIKOBOT_HEADLESS=1 && kikobot-backend c1 |
| systemd | sudo systemctl start kikobot-backend@c1 |
Only one backend instance per robot model should run (lock file prevents duplicates).
Shipped documentation on the PC
| Asset | Path |
|---|---|
| WebSocket guide (Markdown) | /opt/kikobot/share/doc/WEBSOCKET_INTEGRATION_GUIDE.md |
| WebSocket guide (PDF) | /opt/kikobot/share/doc/WEBSOCKET_INTEGRATION_GUIDE.pdf |
| Python example client | /opt/kikobot/share/examples/kikobot_ws_client_example.py |
2. WebSocket API (port 8080)
3.1 Connection
- URL:
ws://<host>:8080(LAN) orws://127.0.0.1:8080(local) - Protocol: UTF-8 JSON, one object per message
- Security: No authentication — use trusted network, VPN, or SSH tunnel only
3.2 Handshake (server → client)
{
"type": "connected",
"message": "Connected to Kikobot C1 WebSocket Bridge",
"robot_profile": "c1",
"capabilities": {
"motion_planning_available": true,
"arc_booklet_available": true,
"hand_teaching_jog": true
}
}
3.3 Keep-alive
{ "type": "ping", "timestamp": 1730000000 }
→ { "type": "pong", "timestamp": 1730000000 }
3.4 C1 bring-up sequence
1. kikobot-backend c1
2. Connect WebSocket
3. { "type": "firmware_status" }
4. { "type": "start_firmware", "port": "/dev/ttyACM0" }
5. Listen for "joint_states" broadcasts
6. { "type": "home" } or motion commands
Firmware paths
C1_FIRMWARE_TYPE | Behavior |
|---|---|
python (default) | Launches /opt/kikobot/share/c1/kikobot_c1_firmware_bridge.py |
microros | Launches micro-ROS agent; ESP must run c1_microros_firmware.ino |
Override script: KIKOBOT_C1_FIRMWARE_SCRIPT in the backend environment.
Serial: Baud 1 000 000 for Python bridge (must match ESP sketch).
{ "type": "start_firmware", "port": "/dev/ttyACM0" }
{ "type": "stop_firmware" }
{ "type": "firmware_status" }
3. Command reference (summary)
Angles are in degrees unless noted. See the full guide on disk for edge cases.
type | Purpose |
|---|---|
home | C1 home pose (firmware + planner sync) |
jog | Single jog step (axis, direction, mode, step, speed) |
hand_teaching | Teach / save / gripper / firmware home (command array) |
motion_plan | Planned MoveJ / MoveL / Arc / Circle |
start_firmware / stop_firmware / firmware_status | ESP32 serial bridge |
save_motor_pose | Read joints from hardware |
fk_request | Forward kinematics |
torque_release / torque_hold | Torque off/on |
hand_teach_points_record | Enable/disable teach point recording |
set_do / get_di | Digital I/O (bridge state) |
start_waypoint_sequence | Optional arc/booklet automation |
run_program / stop_program | Optional Blockly-style runner |
Jog example
{
"type": "jog",
"axis": 0,
"direction": 1,
"mode": 0,
"step": 1.0,
"speed": 0.5
}
mode: 0 = joint, 1 = Cartesian. speed: 0.0–1.0.
Hand teaching (gripper / teach / home)
{ "type": "hand_teaching", "command": [2.0, 0.0, 0.0] }
| teach | save | run | Meaning |
|---|---|---|---|
| 1 | 0 | 0 | Teach mode on |
| 0 | 1 | 0 | Save pose |
| 2 | 0 | 0 | Open gripper |
| 0 | 2 | 0 | Close gripper |
| 3 | 0 | 0 | Home (firmware) |
C1 home joint angles (degrees)
Used by home and planner sync:
[-89.95, -29.52, -88.14, -29.76, 89.95, 89.95]
Joint names in telemetry match the C1 URDF (six revolute joints + gripper via hand teaching).
4. Motion planning (motion_plan)
{
"type": "motion_plan",
"waypoints": [
{
"goal_joint_angles": [-89.95, -29.52, -88.14, -29.76, 89.95, 89.95],
"goal_ee_pose": [],
"motion_type": 0,
"speed_fraction": 0.35,
"sleep_time": 0
},
{
"goal_joint_angles": [-80.0, -25.0, -80.0, -25.0, 85.0, 85.0],
"goal_ee_pose": [],
"motion_type": 0,
"speed_fraction": 0.35,
"sleep_time": 0
}
]
}
motion_type | Name | Waypoints per segment |
|---|---|---|
| 0 | MoveJ | 2 (start joints, goal joints) |
| 1 | MoveL | 2 (TCP pose: mm + deg) |
| 2 | Arc | 3 |
| 3 | Circle | 3 |
Chaining A→B→C: use four waypoints with the middle pose duplicated on the segment boundary (same as Kikobot Studio).
Joint limits (degrees, planner): J1 ±165, J2 ±125, J3–J5 ±140, J6 ±175. Stay slightly inside limits (e.g. J2 ≤ 124.95°).
Success reply:
{ "type": "status", "status": "SUCCESS", "reason": "Motion planning completed successfully" }
5. Telemetry (server → all clients)
type | Content |
|---|---|
joint_states | joint_names, angles (deg), angles_rad — ~30 Hz |
jogging_feedback | During jog |
motion_planning_feedback | During motion_plan; joint_angles in rad |
status | Command results / errors |
motor_pose_saved, fk_result | Pose / FK responses |
Example:
{
"type": "joint_states",
"joint_names": ["Revolute 1", "Revolute 2", "Revolute 3", "Revolute 4", "Revolute 5", "Revolute 6"],
"angles": [-89.95, -29.52, -88.14, -29.76, 89.95, 89.95],
"angles_rad": [-1.57, -0.52, -1.54, -0.52, 1.57, 1.57]
}
6. Reference Python client
pip install 'websockets>=12'
python3 /opt/kikobot/share/examples/kikobot_ws_client_example.py --host 127.0.0.1 status
python3 /opt/kikobot/share/examples/kikobot_ws_client_example.py --host <robot-ip> stream --seconds 10
python3 /opt/kikobot/share/examples/kikobot_ws_client_example.py --host 127.0.0.1 start-firmware --serial /dev/ttyACM0
python3 /opt/kikobot/share/examples/kikobot_ws_client_example.py --host 127.0.0.1 demo-movej
Use --host pointing at the machine where kikobot-backend c1 runs. For C1, pass the ESP serial device (often ttyACM0).
7. ROS 2 interface (advanced)
The backend sources /opt/kikobot/ros/install/setup.bash. Integrators who add native ROS nodes must use the same ROS_DOMAIN_ID as the backend (default 0 if unset).
Typical packages (installed with backend)
urdf_kikobot_description_v1_description— C1 URDF / visualizationkikobot_motion_planner— MoveJ/MoveL/Arc planningcustom_interfaces— services such as motor pose read
Launch entry
kikobot-backend c1 internally runs the display launch, action servers, and bridge. For development from source, see repository start_c1_backend.sh (maintainers only).
Key ROS concepts
| Item | Notes |
|---|---|
| Trajectories | Firmware bridge consumes trajectory points and forwards to ESP |
/joint_states | Published for visualization; firmware bridge polls motor pose |
| RViz | Started unless KIKOBOT_HEADLESS=1 |
8. ESP32 serial protocol (Python bridge)
Host ↔ ESP32 framed binary protocol (CRC16-CCITT). Implemented in kikobot_c1_firmware_bridge.py and c1_serial_firmware.ino.
| Opcode | Direction | Purpose |
|---|---|---|
0x10 OP_TRAJ_POINT | Host→MCU | Trajectory point (6 joints + speed/accel) |
0x11 OP_HAND_TEACH | Host→MCU | Teach / save / gripper / home |
0x12 OP_REQ_HELLO | Host→MCU | Firmware version handshake |
0x13 OP_SCAN_MOTORS | Host→MCU | Scan servo IDs |
0x14 OP_MOTOR_POSE_REQ | Host→MCU | Request current positions |
0x15 OP_TORQUE_CTRL | Host→MCU | Torque enable/disable |
0x21 OP_HELLO | MCU→Host | JSON firmware info |
0x23 OP_MOTOR_POSE | MCU→Host | Joint + gripper positions |
J3/J4 may use sign conventions in firmware; the bridge aligns ROS degrees with servo degrees.
9. Kikobot Studio (UI)
- Application:
kikobot-studioAppImage (version 1.0.0) - Robot selection: Choose C1 on the connection / robot page
- Features: Jog, hand teaching, motion planning, optional camera page (with
KIKOBOT_C1_CAMERA=1) - Studio and your WebSocket client can connect concurrently to port 8080
10. Troubleshooting (software)
| Symptom | Action |
|---|---|
| Cannot connect to 8080 | Start kikobot-backend c1 or systemctl start kikobot-backend@c1 |
robot_profile is c2 | Wrong backend — restart with kikobot-backend c1 |
| Firmware won’t start | Check port, baud 1M, ESP sketch flashed, /tmp/kikobot_firmware.log |
context is invalid on motion | Restart backend (stale ROS context) |
websockets>=12 error | pip3 install --break-system-packages 'websockets>=12' |
| No camera on 8081 | export KIKOBOT_C1_CAMERA=1; install ros-humble-web-video-server |
ss -ltn | grep 8080
tail -f /tmp/kikobot_websocket.log
tail -f /tmp/kikobot_c1_display.log
11. Related documents
- [Installation and Integration](/docs/Kikobot C1/3.4 Installation and Integration)
- [FAQ and Downloads](/docs/Kikobot C1/3.6 FAQ and Downloads)
- [Kikobot C2 software and API](/docs/Kikobot C2/4.2 Software API and ROS) (shared API; C2-specific firmware and home pose)